PostgreSQL Antipatterns: делаем группировку быстрее от 0.1 до 5 раз

Примитивный запрос — простой джойн и группировка. Традиционные методы оптимизации — казалось бы, что могло пойти не так?..

Небольшой эксперимент, на тему необходимости проверки любых гипотез в конкретных условиях.

Возьмем исходный запрос:

WITH vals AS (   SELECT     i   , unnest('{1,2,3,4,5,6,7,8}'::integer[]) v   FROM     generate_series(1, 10000) i ) SELECT   v2.i , sum(v1.v) FROM   vals v1 JOIN   vals v2     USING(i) GROUP BY   1;

294ms — это будет наше стартовое время, которое мы попробуем ускорить. Ну и 640K записей, которые пришлось обработать в Merge Join.

Внимание на ключи группировки!

У нас в запросе используется USING(i) — то есть ON v1.i = v2.i, а потом — GROUP BY 1 — группировка по первому полю результата, которым в нашем случае является v2.i.

То есть происходит группировка по полю связанной таблицы, а сама агрегация — по данным основной таблицы! Не надо так. Этим вы отсекаете планировщику возможность рассмотреть вариант соединения таблиц уже после группировки.

Исправим

Читать далее